package org.wordcorr.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import org.wordcorr.db.*;
import org.wordcorr.gui.action.*;
/**
* Main JFrame for the application.
* @author Keith Hamasaki, Jim Shiba
**/
public final class MainFrame extends JFrame implements Refreshable {
private static final MainFrame INSTANCE = new MainFrame();
public static MainFrame getInstance() {
return INSTANCE;
}
/**
* Constructor.
**/
private MainFrame() {
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
setResizable(true);
}
/**
* Init this frame.
**/
void init() {
_panel = new MainPanel();
setContentPane(_panel);
// Set the font. If the user hasn't chosen one before, set the
// default font to Lucida Sans because that supports IPA
// symbols and is guaranteed to be available with JDK 1.2
final AppPrefs prefs = AppPrefs.getInstance();
String fontStr = prefs.getProperty(AppPrefs.FONT);
if (fontStr == null) {
// default
String fontName = "Lucida Sans";
String[] fonts =
GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for (int i = 0; i < fonts.length; i++) {
if (fonts[i].equalsIgnoreCase("Doulos SIL")) {
// first choice
fontName = fonts[i];
break;
} else if (fonts[i].equalsIgnoreCase("Lucida Sans Unicode")) {
// second choice
fontName = fonts[i];
}
}
setDefaultFont(new Font(fontName, Font.PLAIN, 12));
} else {
setDefaultFont(Font.decode(fontStr));
}
FontCache.setIPA(Font.decode(prefs.getProperty(prefs.IPA_FONT, "Doulos SIL--14")));
FontCache.setPrimaryGloss(Font.decode(prefs.getProperty(prefs.PRIMARY_GLOSS_FONT, "Lucida Sans Unicode--12")));
FontCache.setSecondaryGloss(Font.decode(prefs.getProperty(prefs.SECONDARY_GLOSS_FONT, "Lucida Sans Unicode--12")));
Messages messages = prefs.getMessages();
setTitle(messages.getString("lblAppTitle"));
addWindowListener(Exit.getInstance());
// Load the default database
File file = new File(prefs.getConfigDir(), "database.script");
if (file.exists()) {
openDatabase(file);
} else {
try {
NewLocal.getInstance().createNewDatabase(file);
} catch (DatabaseException e) {
Dialogs.genericError(e);
}
}
// set to the previous size
setLocation(
prefs.getIntProperty(AppPrefs.LOCATION_X, 0),
prefs.getIntProperty(AppPrefs.LOCATION_Y, 0));
setSize(
prefs.getIntProperty(AppPrefs.WIDTH, 640),
prefs.getIntProperty(AppPrefs.HEIGHT, 480));
// refresh to set pane and entry
try {
refresh();
} catch (DatabaseException ignored) {}
// add a component listener to store location/size info
addComponentListener(new ComponentAdapter() {
public void componentMoved(ComponentEvent evt) {
Point point = evt.getComponent().getLocation();
prefs.setProperty(AppPrefs.LOCATION_X, String.valueOf(point.x));
prefs.setProperty(AppPrefs.LOCATION_Y, String.valueOf(point.y));
}
public void componentResized(ComponentEvent evt) {
Dimension dim = evt.getComponent().getSize();
prefs.setProperty(AppPrefs.WIDTH, String.valueOf(dim.width));
prefs.setProperty(AppPrefs.HEIGHT, String.valueOf(dim.height));
}
});
}
/**
* Set the default font for the application.
**/
public void setDefaultFont(Font f) {
FontUIResource font = new FontUIResource(f);
java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
Object key = keys.nextElement();
Object value = UIManager.get(key);
if (value instanceof FontUIResource) {
UIManager.put(key, font);
}
}
SwingUtilities.updateComponentTreeUI(this);
}
/**
* Open a database
* @return true if successful, false if not
**/
public boolean openDatabase(File file) {
AppPrefs prefs = AppPrefs.getInstance();
Messages messages = prefs.getMessages();
// just in case they typed the file name, let's append
// a .script and check for that file
if (!file.exists() && !file.getName().endsWith(".script")) {
file = new File(file.getAbsolutePath() + ".script");
}
if (!file.exists() || !file.getName().endsWith(".script")) {
Dialogs.error(
messages.getCompoundMessage("cmpCannotOpenFile", file.getAbsolutePath()));
return false;
}
String fname = file.getAbsolutePath();
int dotindex = file.getName().indexOf(".");
if (dotindex != -1) {
fname = fname.substring(0, fname.lastIndexOf("."));
}
Database db = DatabaseFactory.openLocalDatabase(new File(fname));
Dialogs.showWaitCursor(this);
try {
switch (db.test()) {
case Database.STATUS_UNINITIALIZED :
Dialogs.error(
messages.getCompoundMessage("cmpCannotOpenFile_2", file.getAbsolutePath()));
return false;
case Database.STATUS_OLD :
if (Dialogs
.confirm(
messages.getCompoundMessage("cmpMigrateFile", file.getAbsolutePath()))) {
db.migrate();
} else {
return false;
}
break;
}
setDatabase(db);
// prefs.setProperty(AppPrefs.LAST_DIR, file.getParentFile().getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
Dialogs.error(
messages.getCompoundMessage(
"cmpCannotOpenFile_3",
new Object[] { file.getAbsolutePath(), e.getMessage()}));
return false;
} finally {
Dialogs.showDefaultCursor(this);
}
return true;
}
/**
* Set the current database.
**/
public void setDatabase(Database db) throws DatabaseException {
// set the state of all disable on close actions
for (Iterator it = _disableOnClose.iterator(); it.hasNext();) {
Action action = (Action) it.next();
action.setEnabled(db != null);
}
// disable all user only actions
setUserOnlyEnabled(false);
final AppPrefs prefs = AppPrefs.getInstance();
if (db != null) {
final DatabasePane pane = new DatabasePane(db);
_panel.setDatabasePane(pane);
pane.setDividerLocation(
AppPrefs.getInstance().getIntProperty(AppPrefs.DIVIDER_LOCATION, 150));
} else {
_panel.setDatabasePane(null);
}
_database = db;
updateStatus();
}
/**
* Get the database.
**/
public Database getDatabase() {
return _database;
}
/**
* Enable or disable all user only actions.
**/
public void setUserOnlyEnabled(boolean flag) {
for (Iterator it = _userOnly.iterator(); it.hasNext();) {
Action action = (Action) it.next();
action.setEnabled(flag);
}
}
/**
* Add an action to the list of disable on close actions.
**/
public void addDisableOnClose(Action action) {
_disableOnClose.add(action);
}
/**
* Add an action to the user only list.
**/
public void addUserOnly(Action action) {
_userOnly.add(action);
}
/**
* Refresh.
**/
public void refresh() throws DatabaseException {
_panel.refresh();
}
/**
* Get the current database.
**/
public DatabasePane getDatabasePane() {
return _panel.getDatabasePane();
}
/**
* Update the status bar.
**/
public void updateStatus() {
try {
String userName = "";
String collectionName = "";
String viewName = "";
DatabasePane dbpane = getDatabasePane();
if (dbpane != null) {
User user = dbpane.getCurrentUser();
if (user != null) {
userName = user.getName();
WordCollection col = dbpane.getCurrentCollection();
if (col != null) {
collectionName = col.getName();
collectionName += (col.getExportTimestamp() == null)
? ""
: " [" + col.getExportTimestamp().toString() + "]";
View view = col.getViewByID(_database.getCurrentSetting().getViewID());
if (view != null) {
viewName = view.getName();
}
}
}
}
Messages messages = AppPrefs.getInstance().getMessages();
_panel._curUser.setText(messages.getString("lblCurrentUser") + " " + userName);
_panel._curCollection.setText(
messages.getString("lblCurrentCollection") + " " + collectionName);
_panel._curView.setText(messages.getString("lblCurrentView") + " " + viewName);
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
* Main panel for this frame.
**/
private final class MainPanel extends JPanel implements Refreshable {
MainPanel() {
super(new BorderLayout());
JPanel status =
new JPanel(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 20, 0));
status.add(_curUser);
status.add(_curCollection);
status.add(_curView);
status.setBorder(BorderFactory.createEtchedBorder());
_menu = new MainMenu();
setJMenuBar(_menu);
this.add(new MainToolBar(), BorderLayout.NORTH);
this.add(status, BorderLayout.SOUTH);
}
public void refresh() throws DatabaseException {
if (_dbpane != null) {
_dbpane.refresh();
}
}
void setDatabasePane(DatabasePane pane) throws DatabaseException {
if (_dbpane != null) {
this.remove(_dbpane);
}
_dbpane = pane;
if (pane != null) {
this.add(pane, BorderLayout.CENTER);
}
}
DatabasePane getDatabasePane() {
return _dbpane;
}
private final class StatusLabel extends JLabel {
StatusLabel(String labelKey) {
super(AppPrefs.getInstance().getMessages().getString(labelKey));
}
}
private final JLabel _curUser = new StatusLabel("lblCurrentUser");
private final JLabel _curView = new StatusLabel("lblCurrentView");
private final JLabel _curCollection = new StatusLabel("lblCurrentCollection");
private DatabasePane _dbpane;
}
/**
* Main Menu for this frame.
**/
private final class MainMenu extends JMenuBar {
MainMenu() {
Messages messages = AppPrefs.getInstance().getMessages();
_fileMenu = new JMenu(messages.getString("mnuFile"));
_fileMenu.setMnemonic(messages.getChar("accFile"));
_fileMenu.add(new WMenuItem(NewUser.getInstance()));
_fileMenu.add(new WMenuItem(NewCollection.getInstance()));
_fileMenu.addSeparator();
_fileMenu.add(new WMenuItem(ImportWordsurv.getInstance()));
_fileMenu.add(new WMenuItem(ImportXML.getInstance()));
_fileMenu.add(new WMenuItem(ExportXML.getInstance()));
_fileMenu.add(new WMenuItem(ExportViewXML.getInstance()));
_fileMenu.add(new WMenuItem(ExportMetadataXML.getInstance()));
_fileMenu.addSeparator();
_fileMenu.add(new WMenuItem(DeleteUser.getInstance()));
_fileMenu.add(new WMenuItem(DeleteCollection.getInstance()));
// Note: Keep replication off menu until ready.
// _fileMenu.addSeparator();
// _fileMenu.add(new WMenuItem(Replicate.getInstance()));
_fileMenu.addSeparator();
_fileMenu.add(new WMenuItem(Exit.getInstance()));
JMenu viewMenu = new JMenu(messages.getString("mnuView"));
viewMenu.setMnemonic(messages.getChar("accView"));
// Note: Remove Refresh
// viewMenu.add(new WMenuItem(Refresh.getInstance()));
viewMenu.add(new WMenuItem(ShowTree.getInstance()));
viewMenu.add(new WMenuItem(ChooseFont.getInstance()));
JMenu helpMenu = new JMenu(messages.getString("mnuHelp"));
helpMenu.setMnemonic(messages.getChar("accHelp"));
helpMenu.add(new WMenuItem(WordcorrHelp.getInstance()));
helpMenu.add(new WMenuItem(About.getInstance()));
this.add(_fileMenu);
this.add(viewMenu);
this.add(helpMenu);
}
private final JMenu _fileMenu;
}
/**
* Main Toolbar for this frame.
**/
private final class MainToolBar extends JToolBar {
MainToolBar() {
setFloatable(false);
add(NewUser.getInstance());
add(NewCollection.getInstance());
// Note Remove Refresh button.
// addSeparator();
// add(Refresh.getInstance());
}
}
private MainPanel _panel;
private MainMenu _menu;
private Database _database;
private final List _disableOnClose = new ArrayList();
private final List _userOnly = new ArrayList();
}